﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GameNode_with_my_node
{
    class NodeGameLogic
    {
        private readonly GameField gameField;
        private readonly Drawer drawer;
        private readonly Random rnd;
        private List<ConsoleNode> nodes;
        private List<ConsoleNode> winnerNodes;
        private ConsoleNode target;
        private int nodeCount;

        public NodeGameLogic(GameField gameField, Drawer drawer, int nodeCount)
        {
            this.gameField = gameField;
            this.drawer = drawer;
            this.nodeCount = nodeCount;

            rnd = new Random();
            nodes = new List<ConsoleNode>();
            winnerNodes = new List<ConsoleNode>();
            target = GenerateRandomTarget((char)1, ConsoleColor.White);

        }


        public void StartGame()
        {
            GenerateRandomNodes();
            AndreyGameNode andrNode = new AndreyGameNode(4, 4, 'A', ConsoleColor.DarkRed);
            nodes.Add(andrNode);

            bool isGameOver = false;
            do
            {
                Console.Clear();
                bool isNewRound = false;
                do
                {
                    drawer.DrawGameField(gameField, '0');
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        nodes[i].Move(CheckPosition);
                    }
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (IsNodeOnTarget(nodes[i]))
                        {
                            winnerNodes.Add(nodes[i]);
                            drawer.DrawListAndMessage(winnerNodes, gameField, 5, "Winners");
                            nodes.RemoveAt(i);
                            if (nodes.Count == 1)
                            {
                                drawer.DrawListAndMessage(nodes, gameField, 15, "Loosers");
                                isNewRound = true;
                                RandomPlacement(winnerNodes);
                            }
                        }
                    }
                    drawer.DrawNodeList(nodes);
                    drawer.DrawNode(target);
                    Thread.Sleep(100);
                }
                while (!isNewRound);

                Console.ReadKey();

                if (winnerNodes.Count == 1)
                {
                    isGameOver = true;
                }
                else
                {
                    nodes = winnerNodes;
                    winnerNodes = new List<ConsoleNode>();
                }

            } while (!isGameOver);
        }

        private ConsoleNode GenerateRandomNode(int nodeCount)
        {

            int randomX = 0;
            int randomY = 0;
            do
            {
                randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
                randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

            } while (!IsPositionFree(randomX, randomY));

            return new ConsoleNode(randomX, randomY, (char)(nodeCount + 41),
                                        (ConsoleColor)rnd.Next(1, 15));
        }

        private ConsoleNode GenerateRandomTarget(char symbol, ConsoleColor color)
        {

            int randomX = 0;
            int randomY = 0;
            do
            {
                randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
                randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

            } while (!IsPositionFree(randomX, randomY));

            return new ConsoleNode(randomX, randomY, symbol, color);
        }

        private void GenerateRandomNodes()

        {
            for (int i = 0; i < nodeCount; i++)
            {
                nodes.Add(GenerateRandomNode(i));
            }
        }

        private bool IsPositionFree(int x, int y)
        {
            foreach (var nd in nodes)
            {
                if (nd.IsOnPossition(x, y))
                    return false;
            }
            return true;
        }

        //private void MoveNodeRandomly(ConsoleNode node)
        //{
        //     int randomMove = rnd.Next(1, 5);
        //     switch (randomMove)
        //     {
        //         case 1:
        //             {
        //                 //MoveUp
        //                 if (IsPositionFree(node.X, node.Y - 1) &&
        //                     gameField.IsOnField(node.X, node.Y - 1))
        //                     node.MoveUp();
        //             }
        //             break;

        //         case 2:
        //             {
        //                 //MoveDown
        //                 if (IsPositionFree(node.X, node.Y + 1) &&
        //                     gameField.IsOnField(node.X, node.Y + 1))
        //                     node.MoveDown();
        //             }
        //             break;

        //         case 3:
        //             {
        //                 //MoveLeft
        //                 if (IsPositionFree(node.X - 1, node.Y) &&
        //                     gameField.IsOnField(node.X - 1, node.Y))
        //                     node.MoveLeft();
        //             }
        //             break;

        //         case 4:
        //             {
        //                 //MoveRight
        //                 if (IsPositionFree(node.X + 1, node.Y) &&
        //                     gameField.IsOnField(node.X + 1, node.Y))
        //                     node.MoveRight();
        //             }
        //             break;
        //     }
        //}

        private bool IsNodeOnTarget(ConsoleNode node)
        {
            if (node.X == target.X && node.Y == target.Y)
                return true;
            return false;
        }

        private void RandomPlacement(List<ConsoleNode> nodes)
        {
            foreach (var node in nodes)
            {
                do
                {
                    node.X = rnd.Next(gameField.X, gameField.Width + gameField.X);
                    node.Y = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

                } while (!IsPositionFree(node.X, node.Y));
            }
        }

        private Position CheckPosition(int x, int y)
        {
            if (!IsPositionFree(x, y))
                return Position.Node;
            if (!gameField.IsOnField(x, y))
                return Position.Border;
            return Position.Free;
        }

    }

    public enum Position
    {
        Node,
        Border,
        Free
    }
}

